package ncme.auto.framework.core.services.Impl.mian;

import ncme.auto.framework.core.callback.AutoProcessControllerPart;
import ncme.auto.framework.core.entities.aspect.parameter.ServiceInfo;
import ncme.auto.framework.core.exceptions.AutoException;
import ncme.auto.framework.core.exceptions.ExceptionEnum;
import ncme.auto.framework.core.services.Impl.base.BaseAutoMapperServiceImpl;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * @author sjh
 * @Description
 * @create 2022/2/14 9:41
 */
public abstract class OneToManyAutoMapperImpl<E, PRIMARY_CLASS, SECONDARY_CLASS> extends BaseAutoMapperServiceImpl<E, PRIMARY_CLASS, SECONDARY_CLASS> {

    public abstract void customService(AutoProcessControllerPart autoProcessControllerPart, ServiceInfo serviceInfo) throws Throwable;

    //region######################################## get ###########################################

    public List<Integer> getSecondaryIdsFromPrimaryId(Integer primaryId) {
        return getIdsFromId(primaryId, true);
    }

    public List<SECONDARY_CLASS> getSecondaryEntitiesFromPrimaryId(Integer primaryId) {
        List<SECONDARY_CLASS> secondaryEntities = new ArrayList<>();
        List<Integer> secondaryIds = getSecondaryIdsFromPrimaryId(primaryId);
        secondaryIds.forEach(secondaryId -> secondaryEntities.add(secondaryEntityBaseService.getEntityById(secondaryId, true)));
        return secondaryEntities;
    }

    public Integer getPrimaryIdFromSecondaryId(Integer secondaryId) {
        List<Integer> fromId = getIdsFromId(secondaryId, false);
        if (fromId.size() > 1)
            throw new AutoException(ExceptionEnum.JDBC, SECONDARY_FIELD_NAME + ":" + secondaryId + "有多个映射关系");
        return fromId.size() == 1 ? fromId.get(0) : null;
    }

    public PRIMARY_CLASS getPrimaryEntityFromSecondaryId(Integer primaryId) {
        Integer secondaryId = getPrimaryIdFromSecondaryId(primaryId);
        return primaryEntityBaseService.getEntityById(secondaryId, true);
    }

    //endregion

    //region######################################## add ###########################################

    public void addSecondaryIdForPrimaryId(Integer primaryId, Integer secondaryId) {
        if (getPrimaryIdFromSecondaryId(secondaryId) != null)  //secondary是否已有映射
            throw new AutoException(ExceptionEnum.JDBC, SECONDARY_FIELD_NAME + ":" + secondaryId + "已存在映射");
        List<Integer> secondaryIds = new ArrayList<>(Collections.singletonList(secondaryId));
        addMappers(primaryId, secondaryIds, true);
    }

    public void addSecondaryIdsForPrimaryId(Integer primaryId, List<Integer> secondaryIds) {
        secondaryIds.forEach(secondaryId -> addSecondaryIdForPrimaryId(primaryId, secondaryId));
    }

    //endregion

    //region######################################## edit #########################################

    public void editSecondaryIdsOfPrimaryId(Integer primaryId, List<Integer> secondaryIds) {
        secondaryIds.forEach(secondaryId -> {
            Integer secondaryId1 = getPrimaryIdFromSecondaryId(secondaryId);
            if (secondaryId1 != null && !secondaryId1.equals(primaryId))  //secondary是否已有其他映射
                throw new AutoException(ExceptionEnum.JDBC, SECONDARY_FIELD_NAME + ":" + secondaryId + "已存在映射");
        });
        editMappers(primaryId, secondaryIds, true);
    }

    public void editPrimaryIdOfSecondaryId(Integer secondaryId, Integer primaryId) {
        List<Integer> primaryIds = new ArrayList<>(Collections.singletonList(primaryId));
        editMappers(secondaryId, primaryIds, false);
    }

    //endregion

    //region######################################## delete ###########################################

    public void deleteSecondaryIdsOfPrimaryId(Integer primaryId, List<Integer> secondaryIds) {
        deleteMappers(primaryId, secondaryIds, true);
    }

    //endregion

}
